home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.sources.misc
- From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
- subject: v08i015: comsat and biff for System V with a FIFO
- Reply-To: edf@ROCKY2.ROCKEFELLER.EDU (David MacKenzie)
-
- Posting-number: Volume 8, Issue 15
- Submitted-by: edf@ROCKY2.ROCKEFELLER.EDU (David MacKenzie)
- Archive-name: comsat.s5
-
- This is a port of the free comsat program from the 4.3BSD-tahoe release
- to System V, with a FIFO (named pipe) replacing sockets.
-
- When a new mail message is delivered, the local mail delivery agent
- writes a message to a FIFO, which the comsat daemon reads. If the
- recipient of the mail is logged in and `biff y' (similar to mesg y but a
- different bit of the tty is used), a message is printed on the user's
- screen summarizing the new mail.
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: README comsat.c biff.c lmail.diffs mailwrap.c
- # Wrapped by dave@edfdc on Wed Aug 23 01:34:53 1989
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(1518 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XThis is a port of the free comsat program from the 4.3BSD-tahoe release
- Xto System V, with a FIFO (named pipe) replacing sockets.
- X
- XWhen a new mail message is delivered, the local mail delivery agent
- Xwrites a message (for the format, see the comment at the top of
- Xcomsat.c) to a FIFO, which the comsat daemon reads. If the recipient
- Xof the mail is logged in and `biff y' (similar to mesg y but a
- Xdifferent bit of the tty is used), a message is printed on the user's
- Xscreen summarizing the new mail.
- X
- XFiles included in this package:
- X
- XREADME This file.
- Xcomsat.c Daemon that prints the biff messages.
- Xbiff.c Allow/prevent receipt of biff messages.
- Xlmail.diffs Diffs to lmail from comp.sources.misc volume 4, a local
- X mail delivery program for smail 2.5, to make it write a
- X message to the comsat FIFO when new mail is delivered.
- Xmailwrap.c An alternative approach to using lmail; a program to
- X write a message to the comsat FIFO, then run your old,
- X renamed local mail delivery program.
- X Written by Jim Mattson <mattson%cs@ucsd.edu>.
- X
- XFollowing is a list of the main portability issues I encountered while
- Xporting comsat from 4.3BSD to System V. In addition to these, I added
- Xmore comments and gave some identifiers more descriptive names, and ran
- Xthe file through GNU indent.
- X
- Xsignals
- Xsockets vs. FIFO
- Xinvocation and exit
- Xerror logging
- Xindex vs. strchr
- Xsgtty vs. termio
- Xgethostname vs. uname
- Xfailure of interrupted system calls (fgets seems to handle this correctly)
- X
- XDavid MacKenzie
- X<edf@rocky2.rockefeller.edu>
- END_OF_FILE
- if test 1518 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'comsat.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'comsat.c'\"
- else
- echo shar: Extracting \"'comsat.c'\" \(11659 characters\)
- sed "s/^X//" >'comsat.c' <<'END_OF_FILE'
- X/*
- X * Copyright (c) 1980 Regents of the University of California.
- X * All rights reserved.
- X *
- X * Redistribution and use in source and binary forms are permitted
- X * provided that the above copyright notice and this paragraph are
- X * duplicated in all such forms and that any documentation,
- X * advertising materials, and other materials related to such
- X * distribution and use acknowledge that the software was developed
- X * by the University of California, Berkeley. The name of the
- X * University may not be used to endorse or promote products derived
- X * from this software without specific prior written permission.
- X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X */
- X
- X#ifndef lint
- Xchar copyright[] =
- X"@(#) Copyright (c) 1980 Regents of the University of California.\n\
- X All rights reserved.\n";
- X#endif /* not lint */
- X
- X/* comsat - daemon to notify registered users of new mail
- X Usage: comsat 2> /tmp/comsat.errors
- X
- X Receives one line messages of the form
- X user@mailbox-offset\n
- X on a named pipe, and if the user is logged on and "biff y" (owner
- X execute bit of tty is turned on), prints a message summarizing the new
- X mail on the user's screen.
- X
- X Converted for System V with FIFO
- X by David MacKenzie <edf@rocky2.rockefeller.edu>
- X with additional changes
- X by Jim Mattson <mattson%cs@ucsd.edu>
- X
- X Latest revision: 08/23/89 */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <utmp.h>
- X#include <signal.h>
- X#include <errno.h>
- X#include <fcntl.h>
- X#include <termio.h>
- X#include <string.h>
- X#include <varargs.h>
- X#include <sys/utsname.h>
- X
- X/* BSD-compatible constants for lseek. */
- X#define L_SET 0
- X#define L_INCR 1
- X#define L_XTND 2
- X
- X/* The directory where system mailboxes are located. */
- X#define SYSMAILDIR "/usr/mail"
- X
- X/* Path of the named pipe used to send messages to this program. */
- X#define FIFO "/etc/comsat.fifo"
- X
- X/* The number of seconds between checks of the utmp. */
- X#define ALARM_INTERVAL 15
- X
- X/* If this is defined, no blank line will be printed between the
- X header lines (e.g., "Subject:") and the head of the message text.
- X The blank line is present in the 4.3BSD comsat but absent in the
- X 4.3BSD-tahoe comsat from which this version is derived. */
- X/* #define JOIN_HEADER_AND_TEXT */
- X
- Xchar *malloc ();
- Xchar *realloc ();
- Xoff_t atol ();
- Xoff_t fseek ();
- Xoff_t lseek ();
- Xtime_t time ();
- X
- Xchar *xmalloc ();
- Xchar *xrealloc ();
- Xint read_utmp ();
- Xint note_alarm ();
- Xvoid mail_for ();
- Xvoid msg_perror_fatal ();
- Xvoid notify ();
- Xvoid summarize_new_mail ();
- X
- X/* This machine's host name, used in the notification message. */
- Xchar hostname[10];
- X
- X/* Contents of the utmp. */
- Xstruct utmp *utmp;
- X
- X/* If nonzero, the alarm rang while sending a biff message. */
- Xint alarm_rang;
- X
- X/* Number of entries in `utmp'. */
- Xint nutmp;
- X
- X/* File descriptor for reading the utmp. */
- Xint utfd;
- X
- X/* The name this program was run with, for error messages. */
- Xchar *program_name;
- X
- X/* ARGSUSED */
- Xint
- Xmain (argc, argv)
- X int argc;
- X char **argv;
- X{
- X FILE *fifp;
- X char msgbuf[100];
- X
- X program_name = argv[0];
- X
- X signal (SIGINT, SIG_IGN);
- X signal (SIGHUP, SIG_IGN);
- X
- X /* Don't tie up a filesystem. */
- X if (chdir ("/") == -1)
- X msg_perror_fatal ("Cannot chdir to /");
- X
- X if (daemon_running (FIFO))
- X {
- X fprintf (stderr, "%s: Daemon is already running\n", program_name);
- X exit (1);
- X }
- X switch (fork ())
- X {
- X case -1:
- X msg_perror_fatal ("Cannot fork");
- X case 0: /* Child. */
- X break;
- X default: /* Parent. */
- X _exit (0);
- X }
- X
- X fclose (stdin); /* Don't need these anymore. */
- X fclose (stdout);
- X setpgrp (); /* Detach from parent's process group. */
- X
- X fifp = fdopen (open_fifo (FIFO), "r");
- X if (fifp == NULL)
- X msg_perror_fatal ("Cannot fdopen FIFO %s", FIFO);
- X
- X utfd = open (UTMP_FILE, O_RDONLY);
- X if (utfd == -1)
- X msg_perror_fatal ("Cannot read %s", UTMP_FILE);
- X
- X utmp = NULL;
- X nutmp = 0;
- X gethostname (hostname, sizeof (hostname));
- X signal (SIGCLD, SIG_IGN); /* Prevent zombie process creation. */
- X
- X read_utmp ();
- X
- X while (1)
- X {
- X while (fgets (msgbuf, sizeof msgbuf, fifp) == NULL)
- X sleep (1);
- X if (nutmp == 0)
- X continue; /* No one has logged in yet. */
- X /* Don't let automatic utmp updating corrupt the in-core copy while
- X we're using it. */
- X alarm_rang = 0;
- X signal (SIGALRM, note_alarm);
- X mail_for (msgbuf);
- X /* If we missed a utmp update while biffing the user, do the
- X update manually and set the alarm again. */
- X if (alarm_rang)
- X read_utmp ();
- X else
- X signal (SIGALRM, read_utmp);
- X }
- X /* NOTREACHED */
- X}
- X
- X/* SIGALRM handler for while mail_for is running. */
- X
- Xint
- Xnote_alarm ()
- X{
- X alarm_rang = 1;
- X}
- X
- X/* Normal SIGALRM handler. Every ALARM_INTERVAL seconds, read a current
- X copy of the utmp into `utmp'. */
- X
- Xint
- Xread_utmp ()
- X{
- X static unsigned utmp_size = 0;/* Bytes allocated for `utmp'. */
- X static unsigned utmp_mtime = 0; /* Last modification time of utmp. */
- X struct stat stats;
- X
- X if (fstat (utfd, &stats) == -1)
- X msg_perror_fatal ("Cannot fstat utmp");
- X if (stats.st_mtime > utmp_mtime)
- X {
- X utmp_mtime = stats.st_mtime;
- X if (stats.st_size > utmp_size)
- X {
- X utmp_size = stats.st_size + 10 * sizeof (struct utmp);
- X utmp = (struct utmp *) xrealloc ((char *) utmp, utmp_size);
- X }
- X if (lseek (utfd, 0L, L_SET) < 0)
- X msg_perror_fatal ("Cannot seek to beginning of utmp");
- X nutmp = read (utfd, utmp, (unsigned) stats.st_size);
- X if (nutmp == -1)
- X msg_perror_fatal ("Cannot read utmp");
- X nutmp /= sizeof (struct utmp);
- X }
- X alarm ((unsigned) ALARM_INTERVAL);
- X signal (SIGALRM, read_utmp);
- X}
- X
- X/* `name' has the form "user@mailbox-offset\n". Check whether "user" is
- X logged on; if so, try to notify them of the new mail. */
- X
- Xvoid
- Xmail_for (name)
- X char *name;
- X{
- X struct utmp *utp;
- X char *cp;
- X off_t offset;
- X
- X cp = strchr (name, '@');
- X if (cp == NULL)
- X {
- X fprintf (stderr, "%s: Invalid message: %s\n", program_name, name);
- X return;
- X }
- X *cp++ = '\0';
- X offset = atol (cp);
- X utp = &utmp[nutmp];
- X while (--utp >= utmp)
- X {
- X if (!strncmp (utp->ut_user, name, sizeof (utmp[0].ut_user)))
- X notify (utp, offset);
- X }
- X}
- X
- X/* The carriage return character needed for the terminal being notified;
- X it will be the null string if the terminal driver or the terminal
- X is supplying a carriage return automatically with each newline. */
- Xstatic char *cr;
- X
- X/* If the user described in `utp' is logged on and "biff y", notify them
- X of the new mail in their system mailbox at offset `offset'. */
- X
- Xvoid
- Xnotify (utp, offset)
- X struct utmp *utp;
- X off_t offset;
- X{
- X static char tty[20] = "/dev/";
- X struct termio termio;
- X FILE *tp;
- X char name[sizeof (utmp[0].ut_user) + 1];
- X struct stat stats;
- X int i;
- X
- X strncpy (tty + 5, utp->ut_line, sizeof (utp->ut_line));
- X while ((i = stat (tty, &stats)) == -1 && errno == EINTR)
- X /* Do nothing. */ ;
- X if (i == -1 || !(stats.st_mode & S_IEXEC))
- X return;
- X switch (fork ())
- X {
- X case -1:
- X msg_perror_fatal ("Cannot fork");
- X case 0: /* Child. */
- X break;
- X default: /* Parent. */
- X return;
- X }
- X signal (SIGALRM, SIG_DFL);
- X alarm ((unsigned) 30);
- X tp = fopen (tty, "w");
- X if (tp == NULL)
- X _exit (1);
- X ioctl (fileno (tp), TCGETA, &termio);
- X cr = (termio.c_oflag & OPOST) && (termio.c_oflag & ONLCR)
- X || (termio.c_oflag & ONLRET) ? "" : "\r";
- X strncpy (name, utp->ut_user, sizeof (utp->ut_user));
- X name[sizeof (name) - 1] = '\0';
- X fprintf (tp, "%s\n\007New mail for %s@%.*s\007 has arrived:%s\n----%s\n",
- X cr, name, sizeof (hostname), hostname, cr, cr);
- X summarize_new_mail (tp, name, offset);
- X fclose (tp);
- X _exit (0);
- X}
- X
- X/* Print the first 7 lines or 560 characters (whichever comes first) of
- X the new mail message that starts at byte `offset' in the system
- X mailbox for user `name' to stream `tp'. Skip header lines other than
- X From, Subject, [To, and Date]. */
- X
- Xvoid
- Xsummarize_new_mail (tp, name, offset)
- X FILE *tp;
- X char *name;
- X off_t offset;
- X{
- X char *cp;
- X FILE *fi;
- X int linecnt;
- X int charcnt;
- X int inheader;
- X char line[BUFSIZ];
- X
- X cp = xmalloc (sizeof (SYSMAILDIR) + strlen (name) + 2);
- X sprintf (cp, "%s/%s", SYSMAILDIR, name);
- X fi = fopen (cp, "r");
- X free (cp);
- X if (fi == NULL)
- X return;
- X if (fseek (fi, offset, L_SET))
- X return;
- X linecnt = 7;
- X charcnt = 560;
- X inheader = 1;
- X
- X while (fgets (line, sizeof (line), fi) != NULL)
- X {
- X if (inheader)
- X {
- X if (line[0] == '\n')
- X {
- X inheader = 0;
- X#ifdef JOIN_HEADER_AND_TEXT
- X continue;
- X#endif
- X }
- X else if (line[0] == ' ' || line[0] == '\t'
- X || strncmp (line, "From:", 5)
- X && strncmp (line, "Subject:", 8))
- X /* Skip header continuation lines and non-essential header lines. */
- X continue;
- X }
- X if (linecnt <= 0 || charcnt <= 0)
- X {
- X fprintf (tp, "...more...%s\n", cr);
- X return;
- X }
- X cp = strchr (line, '\n');
- X if (cp)
- X *cp = '\0';
- X fprintf (tp, "%s%s\n", line, cr);
- X charcnt -= strlen (line);
- X linecnt--;
- X }
- X fprintf (tp, "----%s\n", cr);
- X}
- X
- X/* Simulate the BSD gethostname(2) system call on System V. */
- X
- Xint
- Xgethostname (name, length)
- X char *name;
- X int length;
- X{
- X struct utsname uts;
- X
- X if (uname (&uts) < 0)
- X return -1;
- X strncpy (name, uts.nodename, length);
- X return 0;
- X}
- X
- Xstatic void
- Xmemory_out ()
- X{
- X fprintf (stderr, "%s: Virtual memory exhausted\n", program_name);
- X exit (1);
- X}
- X
- X/* Allocate `n' bytes of memory dynamically, with error checking. */
- X
- Xchar *
- Xxmalloc (n)
- X unsigned n;
- X{
- X char *p;
- X
- X p = malloc (n);
- X if (p == 0)
- X memory_out ();
- X return p;
- X}
- X
- X/* Change the size of an allocated block of memory `p' to `n' bytes,
- X with error checking.
- X If `p' is NULL, run xmalloc.
- X If `n' is 0, run free and return NULL. */
- X
- Xchar *
- Xxrealloc (p, n)
- X char *p;
- X unsigned n;
- X{
- X if (p == 0)
- X return xmalloc (n);
- X if (n == 0)
- X {
- X free (p);
- X return 0;
- X }
- X p = realloc (p, n);
- X if (p == 0)
- X memory_out ();
- X return p;
- X}
- X
- X/* ANSI C function. */
- X
- Xchar *
- Xstrerror (n)
- X int n;
- X{
- X extern char *sys_errlist[];
- X extern int sys_nerr;
- X
- X return n >= 0 && n < sys_nerr ? sys_errlist[n] : "Unknown error";
- X}
- X
- X/* Print "program_name: str_and_optional_args: perror_message" on stderr,
- X then exit with error status. */
- X/* VARARGS */
- Xvoid
- Xmsg_perror_fatal (str, va_alist)
- X char *str;
- X va_dcl
- X{
- X va_list args;
- X extern int errno;
- X int save_errno;
- X
- X save_errno = errno;
- X fprintf (stderr, "%s: ", program_name);
- X va_start (args);
- X vfprintf (stderr, str, args);
- X va_end (args);
- X fprintf (stderr, ": %s\n", strerror (save_errno));
- X exit (1);
- X}
- X
- X/* Open `path' for reading as a mode 0600 FIFO, creating it if necessary.
- X Return the file descriptor. */
- X
- Xint
- Xopen_fifo (path)
- X char *path;
- X{
- X int fifd;
- X
- X if (mknod (path, 010600, 0) == -1 && errno != EEXIST)
- X msg_perror_fatal ("Cannot create FIFO %s", path);
- X if (chmod (path, 0600))
- X msg_perror_fatal ("Cannot change mode of FIFO %s", path);
- X while ((fifd = open (path, O_RDONLY | O_TRUNC)) == -1 && errno == EINTR)
- X /* Do nothing. */ ;
- X if (fifd == -1)
- X msg_perror_fatal ("Cannot open FIFO %s for reading", path);
- X return fifd;
- X}
- X
- X/* Return nonzero if there is another process already reading `fifo'.
- X If there isn't, open will fail with EPIPE (write on broken pipe). */
- X
- Xint
- Xdaemon_running (fifo)
- X char *fifo;
- X{
- X int fifd;
- X
- X fifd = open (fifo, O_WRONLY | O_NDELAY);
- X if (fifd == -1)
- X return 0;
- X else
- X {
- X close (fifd);
- X return 1;
- X }
- X}
- END_OF_FILE
- if test 11659 -ne `wc -c <'comsat.c'`; then
- echo shar: \"'comsat.c'\" unpacked with wrong size!
- fi
- # end of 'comsat.c'
- fi
- if test -f 'biff.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'biff.c'\"
- else
- echo shar: Extracting \"'biff.c'\" \(2171 characters\)
- sed "s/^X//" >'biff.c' <<'END_OF_FILE'
- X/* biff - accept or refuse new mail messages from comsat
- X
- X Usage: biff [yn]
- X
- X David MacKenzie
- X public domain
- X Latest revision: 08/19/89 */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <varargs.h>
- X
- Xchar *ttyname ();
- X
- Xchar *any_ttyname ();
- Xvoid msg_perror_fatal ();
- Xvoid usage ();
- X
- Xchar *program_name;
- X
- Xint
- Xmain (argc, argv)
- X int argc;
- X char **argv;
- X{
- X struct stat stats;
- X char *tty;
- X
- X program_name = argv[0];
- X tty = any_ttyname ();
- X if (tty == NULL)
- X {
- X fprintf (stderr, "%s: Not connected to a terminal\n", argv[0]);
- X exit (1);
- X }
- X if (stat (tty, &stats) == -1)
- X msg_perror_fatal ("Cannot stat %s", tty);
- X switch (argc)
- X {
- X case 1:
- X printf ("is %c\n", (stats.st_mode & S_IEXEC) ? 'y' : 'n');
- X break;
- X case 2:
- X if (*argv[1] == '-')
- X ++argv[1]; /* Allow '-y' or 'y'. */
- X switch (*argv[1])
- X {
- X case 'y':
- X if (chmod (tty, stats.st_mode | S_IEXEC) == -1)
- X msg_perror_fatal ("Cannot change mode of %s", tty);
- X break;
- X case 'n':
- X if (chmod (tty, stats.st_mode & ~S_IEXEC) == -1)
- X msg_perror_fatal ("Cannot change mode of %s", tty);
- X break;
- X default:
- X usage ();
- X }
- X break;
- X default:
- X usage ();
- X }
- X exit (0);
- X /* NOTREACHED */
- X}
- X
- Xchar *
- Xany_ttyname ()
- X{
- X char *tty;
- X
- X tty = ttyname (2);
- X if (tty)
- X return tty;
- X tty = ttyname (1);
- X if (tty)
- X return tty;
- X tty = ttyname (0);
- X if (tty)
- X return tty;
- X return NULL;
- X}
- X
- X/* ANSI C function. */
- X
- Xchar *
- Xstrerror (n)
- X int n;
- X{
- X extern char *sys_errlist[];
- X extern int sys_nerr;
- X
- X return n >= 0 && n < sys_nerr ? sys_errlist[n] : "Unknown error";
- X}
- X
- X/* Print "program_name: str_and_optional_args: perror_message" on stderr,
- X then exit with error status. */
- X/* VARARGS */
- Xvoid
- Xmsg_perror_fatal (str, va_alist)
- X char *str;
- X va_dcl
- X{
- X va_list args;
- X extern int errno;
- X int save_errno;
- X
- X save_errno = errno;
- X fprintf (stderr, "%s: ", program_name);
- X va_start (args);
- X vfprintf (stderr, str, args);
- X va_end (args);
- X fprintf (stderr, ": %s\n", strerror (save_errno));
- X exit (1);
- X}
- X
- Xvoid
- Xusage ()
- X{
- X fprintf (stderr, "Usage: %s [yn]\n", program_name);
- X exit (1);
- X}
- END_OF_FILE
- if test 2171 -ne `wc -c <'biff.c'`; then
- echo shar: \"'biff.c'\" unpacked with wrong size!
- fi
- # end of 'biff.c'
- fi
- if test -f 'lmail.diffs' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lmail.diffs'\"
- else
- echo shar: Extracting \"'lmail.diffs'\" \(1782 characters\)
- sed "s/^X//" >'lmail.diffs' <<'END_OF_FILE'
- X*** lmail.c.dist Tue Aug 15 03:34:47 1989
- X--- lmail.c Wed Aug 16 02:30:06 1989
- X***************
- X*** 527,532 ****
- X--- 527,533 ----
- X return(8);
- X }
- X } else {
- X+ long where = -1, ftell ();
- X setgid(MAILGID);
- X setuid(pwd_mailman->pw_uid); /* give up root uid */
- X sprintf(temp, "%s%s", MAIL_DIR, dest);
- X***************
- X*** 535,542 ****
- X if ((outfile = fopen(temp, "a")) == NULL) {
- X (void) fprintf(stderr, "** Can't open user mail file %s\n", temp);
- X status = 5;
- X! } else
- X copy(outfile, in_fd, author);
- X chown(temp, (int)pwd->pw_uid, MAILGID);
- X if (fclose(outfile)) {
- X (void) fprintf(stderr, "** Could not close mail file %s\n", temp);
- X--- 536,545 ----
- X if ((outfile = fopen(temp, "a")) == NULL) {
- X (void) fprintf(stderr, "** Can't open user mail file %s\n", temp);
- X status = 5;
- X! } else {
- X! where = ftell(outfile);
- X copy(outfile, in_fd, author);
- X+ }
- X chown(temp, (int)pwd->pw_uid, MAILGID);
- X if (fclose(outfile)) {
- X (void) fprintf(stderr, "** Could not close mail file %s\n", temp);
- X***************
- X*** 543,548 ****
- X--- 546,553 ----
- X status = 7;
- X }
- X unlock(temp);
- X+ if (where != -1)
- X+ biff(dest, where);
- X _exit(status);
- X }
- X }
- X***************
- X*** 626,629 ****
- X--- 631,651 ----
- X return;
- X }
- X
- X+ #include <fcntl.h>
- X+
- X+ /* Do our best to biff the recipient. Errors don't bother us. */
- X
- X+ biff (user, offset)
- X+ char *user;
- X+ long offset;
- X+ {
- X+ int fd;
- X+ char biffbuf[30];
- X+
- X+ fd = open ("/etc/comsat.fifo", O_WRONLY | O_NDELAY);
- X+ if (fd == -1)
- X+ return;
- X+ sprintf (biffbuf, "%s@%ld\n", user, offset);
- X+ write (fd, biffbuf, strlen (biffbuf));
- X+ close (fd);
- X+ }
- END_OF_FILE
- if test 1782 -ne `wc -c <'lmail.diffs'`; then
- echo shar: \"'lmail.diffs'\" unpacked with wrong size!
- fi
- # end of 'lmail.diffs'
- fi
- if test -f 'mailwrap.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'mailwrap.c'\"
- else
- echo shar: Extracting \"'mailwrap.c'\" \(1624 characters\)
- sed "s/^X//" >'mailwrap.c' <<'END_OF_FILE'
- X/* Local Mail Interceptor to handle interface to comsat */
- X/* Args for local mail are [ -r sender ] parties ... */
- X/* Jim Mattson <mattson%cs@ucsd.edu> */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X#include <stdio.h>
- X
- X#define FIFO "/usr/tmp/comsat.fifo"
- X#define MAILDIR "/usr/spool/mail"
- X#define MAILER "/usr/lib/mail/mail.orig"
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X{
- X off_t *offsets; /* Mailbox offsets before delivery */
- X struct stat stbuf; /* For stat'ing mailboxes */
- X char **av = argv; /* Old argv */
- X int fd; /* file descriptor for FIFO */
- X FILE *fp; /* File pointer for FIFO */
- X int rc; /* Return Code from local mailer */
- X int i;
- X
- X /* Get rid of program name and [ -r sender ] */
- X argc--;
- X argv++;
- X if(!strcmp(argv[0], "-r")) {
- X argc -= 2;
- X argv += 2;
- X }
- X if(argc == 0)
- X exit(0);
- X
- X if((offsets = (off_t *)malloc(sizeof(off_t) * argc)) == NULL)
- X bailout(av);
- X
- X /* Get mailbox offsets */
- X if(chdir(MAILDIR) < 0)
- X bailout(av);
- X for(i = 0; i < argc; i++) {
- X if(stat(argv[i], &stbuf) < 0)
- X offsets[i] = 0;
- X else
- X offsets[i] = stbuf.st_size;
- X }
- X
- X /* Send mail and wait for exit code */
- X switch(fork()) {
- X case -1:
- X case 0:
- X bailout(av); /* No return */
- X default:
- X wait(&rc);
- X }
- X /* Send messages to comsat if it's listening */
- X if((fd = open(FIFO, O_WRONLY | O_NDELAY)) >= 0) {
- X if((fp = fdopen(fd, "w")) != NULL) {
- X for(i = 0; i < argc; i++)
- X fprintf(fp, "%s@%d\n", argv[i], offsets[i]);
- X fclose(fp);
- X }
- X close(fd);
- X }
- X /* Exit with local mailer's return code */
- X exit(rc >> 8);
- X}
- X
- Xbailout(argv)
- Xchar **argv;
- X{
- X argv[0] = MAILER;
- X execv(MAILER, argv);
- X _exit(0);
- X}
- END_OF_FILE
- if test 1624 -ne `wc -c <'mailwrap.c'`; then
- echo shar: \"'mailwrap.c'\" unpacked with wrong size!
- fi
- # end of 'mailwrap.c'
- fi
- echo shar: End of shell archive.
- exit 0
-
-